#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <memory>
#include <thread>
#include "log.hpp"
#include "Common.hpp"

static bool isrunning = false;
static std::string Clientname;

class Client
{
public:
    Client(const std::string &server_ip, uint16_t server_port)
    {
        _sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (_sockfd == -1)
        {
            perror("socket creation failed");
            exit(EXIT_FAILURE);
        }

        memset(&_serverAddr, 0, sizeof(_serverAddr));
        _serverAddr.sin_family = AF_INET;
        _serverAddr.sin_port = htons(server_port);
        if (inet_pton(AF_INET, server_ip.c_str(), &_serverAddr.sin_addr) <= 0)
        {
            perror("inet_pton failed");
            close(_sockfd);
            exit(EXIT_FAILURE);
        }

        _isrunning = true;
    }
    void start()
    {
        std::cout << "你是? ";
        std::cin >> _clientName;
        std::cout << "可以进行通信了!" << std::endl;

        std::thread recvThread(&Client::receive, this);
        std::thread sendThread(&Client::send, this);

        recvThread.detach();
        sendThread.detach();

        while (_isrunning)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }

        close(_sockfd);
    }

private:
    void receive()
    {
        while (_isrunning)
        {
            char buffer[1024] = {0};
            struct sockaddr_in peer;
            socklen_t socklen = sizeof(peer);

            ssize_t n = recvfrom(_sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&peer, &socklen);
            if (n > 0)
            {
                buffer[n] = 0;
                std::cout << "server: " << buffer << std::endl;
            }
            else if (n == -1)
            {
                perror("recvfrom error");
            }
        }
    }
     void send()
    {
        while (_isrunning)
        {
            std::cout << _clientName << ": ";
            std::string message;
            std::cin >> message;

            ssize_t sent = sendto(_sockfd, message.c_str(), message.size(), 0, (struct sockaddr *)&_serverAddr, sizeof(_serverAddr));
            if (sent == -1)
            {
                perror("sendto error");
            }
        }
    }

private:
    int _sockfd;
    struct sockaddr_in _serverAddr;
    bool _isrunning;
    std::string _clientName;
};

void useagge(std::string proc)
{
    std::cout << "Usage:\n\t" << proc << " serverip serverport\n"
              << std::endl;
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        useagge(argv[0]);
        exit(USAGE_ERROR);
    }
    std::string serverip = argv[1];
    uint16_t serverport = std::atoi(argv[2]);
    std::unique_ptr<Client> csvr = std::make_unique<Client>(serverip, serverport); // C++14
    csvr->start();
    return 0;
}

//    std::string serverip = argv[1];
//     uint16_t serverport = std::atoi(argv[2]);
//     std::cout << "你是?" << std::endl;
//     std::cin >> Clientname;
//     // 创建socket;
//     int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
//     if (sockfd < 0)
//     {
//         LOG(WARNING, "%s", "Sock错误创建失败");
//     }
//     LOG(INFO, "%s", "sock创建成功");
//     isrunning = true;

//     struct sockaddr_in server;
//     socklen_t Ssocklen = sizeof(server);
//     Setserver(server, serverip, serverport);
//     // struct sockaddr_in local;
//     std::cout << "可以进行通信了!" << std::endl;

//     while (isrunning)
//     {
//         std::cout << Clientname << ":";
//         std::string message;
//         std::cin >> message;
//         ssize_t sent = sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr *)&server, Ssocklen); // 发送
//         if (sent == -1)
//         {
//             perror("sendto error");
//             continue;
//         }
//         ////////////////////////////////////
//         struct sockaddr_in peer;
//         socklen_t socklen = sizeof(peer);
//         char buffer[1024] = {0}; // 初始化缓冲区

//         ssize_t n = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&peer, &socklen);
//         if (n > 0) {
//             buffer[n] = 0; // 确保字符串以零结尾
//             std::cout << "server: " << buffer << std::endl;
//         } else if (n == -1) {
//             perror("recvfrom error");
//         }
//     }